package com.batis.source.parsing;

import org.apache.ibatis.parsing.PropertyParser;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * xml 文件中的一个节点数据 进行了二次封装
 * @author isam2016
 * @create 2021-08-27 9:53 AM
 */
public class MYXnode {

    private Node node;
    private String name;
    private String body;
    private Properties attributes;
    private Properties variables;
    private MYXPathParser xpathParser;

    public MYXnode(MYXPathParser myxPathParser, Node node, Properties variables){
        this.xpathParser = myxPathParser;
        this.node = node;
        this.name = node.getNodeName();
        this.attributes = parseAttributes(node);
    }

    public MYXnode evalNode(String expression) {
        return xpathParser.evalNode(node, expression);
    }

    public MYXnode getParent() {
        Node parent = node.getParentNode();
        if (parent == null || !(parent instanceof Element)) {
            return null;
        } else {
            return new MYXnode(xpathParser, parent, variables);
        }
    }

    private Properties parseAttributes(Node n) {
        Properties attributes = new Properties();
        NamedNodeMap attributeNodes = n.getAttributes();
        if (attributeNodes != null) {
            for (int i = 0; i < attributeNodes.getLength(); i++) {
                Node attribute = attributeNodes.item(i);
                String value = PropertyParser.parse(attribute.getNodeValue(), variables);
                attributes.put(attribute.getNodeName(), value);
            }
        }
        return attributes;
    }

    public List<MYXnode> getChildren() {
        List<MYXnode> children = new ArrayList<>();
        NodeList nodeList = node.getChildNodes();
        if (nodeList != null) {
            for (int i = 0, n = nodeList.getLength(); i < n; i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    children.add(new MYXnode(xpathParser, node, variables));
                }
            }
        }
        return children;
    }

    public String getStringAttribute(String name) {
        return getStringAttribute(name, null);
    }

    public String getStringAttribute(String name, String def) {
        String value = attributes.getProperty(name);
        if (value == null) {
            return def;
        } else {
            return value;
        }
    }

    public Properties getChildrenAsProperties() {
        Properties properties = new Properties();
        for (MYXnode child : getChildren()) {
            String name = child.getStringAttribute("name");
            String value = child.getStringAttribute("value");
            if (name != null && value != null) {
                properties.setProperty(name, value);
            }
        }
        return properties;
    }
}
